package com.a863.hooklearn.util;

import android.content.Context;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 参考文档：https://blog.csdn.net/acxingyun/article/details/78742002
 * Created by yyd on 2018/10/10.
 */
public class HookUtil {
    private Class<?> proxyActivity;
    private Context context;

    public HookUtil(Class<?> proxyActivity, Context context) {
        this.proxyActivity = proxyActivity;
        this.context = context;
    }

    public void hookAms(){
        try{
            //通过完整的类名拿到class
            Class<?> ActivityManagerNativeClss=Class.forName("android.app.ActivityManagerNative");
            //拿到这个类的某个field
            Field gDefaultField=ActivityManagerNativeClss.getDeclaredField("gDefault");
            //field为private，设置为可访问的
            gDefaultField.setAccessible(true);
            //拿到ActivityManagerNative的gDefault的Field的实例
            //gDefault为static类型，不需要传入具体的对象
            Object gDefaultFieldValue=gDefaultField.get(null);

            //拿到Singleton类
            Class<?> SingletonClass=Class.forName("android.util.Singleton");
            //拿到类对应的field
            Field mInstanceField=SingletonClass.getDeclaredField("mInstance");
            //field是private
            mInstanceField.setAccessible(true);
            //gDefaultFieldValue是Singleton的实例对象
            //拿到IActivityManager
            Object iActivityManagerObject=mInstanceField.get(gDefaultFieldValue);

            AmsInvocationHandler handler=new AmsInvocationHandler(iActivityManagerObject);
            Class<?> IActivityManagerIntercept=Class.forName("android.app.IActivityManager");
            Object proxy= Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class<?>[]{IActivityManagerIntercept},handler);
            mInstanceField.set(gDefaultFieldValue,proxy);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private class AmsInvocationHandler implements InvocationHandler{
        private Object iActivityManagerObject;

        public AmsInvocationHandler(Object iActivityManagerObject) {
            this.iActivityManagerObject = iActivityManagerObject;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Log.i("HookUtil",method.getName());

            if("startActivity".contains(method.getName())){
                Log.e("HookUtil","Activity已经开始启动");
                Log.e("HookUtil","小弟到此一游");
            }
            return method.invoke(iActivityManagerObject,args);
        }
    }
}
